import { computed, watch, ref, onUnmounted, nextTick } from 'vue';
import find from 'lodash-es/find.js';
import get from 'lodash-es/get.js';

export const GROUP_PROPS = {
  modelValue: { type: [String, Number], default: '' },
  dataList: { type: Array, default: () => [] },
  format: { type: Function, default: undefined },
  /*replaceFields: { label: "label", value: "value", key: "value" }*/
  replaceFields: { type: Object, default: () => ({}) },
};

export default function useGroup(props, ctx) {
  /* key 的键值必须唯一，key 值默认与 value 值一致，value 的键值作为最后输出值 */
  let defaultFields = { label: 'label', value: 'value' };
  let fields = computed(() => {
    let fieldsData = Object.assign({}, defaultFields, props.replaceFields);
    if (fieldsData.key === undefined) {
      fieldsData.key = fieldsData.value;
    }
    return fieldsData;
  });

  let formatter = function (item) {
    if (typeof props.format === 'function') {
      return props.format(item);
    }
    return item[fields.value.label];
  };

  let dataSource = computed(() => {
    if (!Array.isArray(props.dataList)) {
      return [];
    }
    return props.dataList
      .filter((item) => item && typeof item === 'object')
      .map((item) => {
        return Object.assign({}, item, {
          label: formatter(item),
          value: item[fields.value.value],
          key: item[fields.value.key],
        });
      });
  });

  let getData = function (field, value, valueKey) {
    let data = find(dataSource.value, (item) => item[field] === value);
    return valueKey !== undefined ? get(data, valueKey) : data;
  };

  let output = function (modelValue, value) {
    ctx.emit('update:modelValue', modelValue);
    nextTick(() => {
      ctx.emit('change', value !== undefined ? value : modelValue);
    });
  };

  let value = ref(undefined);
  watch(
    () => props.modelValue,
    (modelValue) => (value.value = modelValue),
    { immediate: true }
  );

  onUnmounted(() => {
    defaultFields = null;
    dataSource = null;
    fields = null;
    value = null;
    formatter = null;
    getData = null;
    output = null;
  });

  return { dataSource, value, fields, formatter, getData, output };
}
